package com.examplemartin.jpademo.controller.admin;

import com.examplemartin.jpademo.bean.AjaxResult;
import com.examplemartin.jpademo.bean.Site;
import com.examplemartin.jpademo.pojo.admin.OperatorLogPO;
import com.examplemartin.jpademo.pojo.po.DatabasePO;
import com.examplemartin.jpademo.pojo.po.UserPO;
import com.examplemartin.jpademo.service.UserService;
import com.examplemartin.jpademo.service.admin.DatabaseService;
import com.examplemartin.jpademo.service.admin.OperatorLogService;
import com.examplemartin.jpademo.util.DateUtil;
import com.examplemartin.jpademo.util.SessionUtil;
import com.examplemartin.jpademo.util.ValidateMember;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping("/database")
@Slf4j
public class DatabaseController {

    @Resource
    private OperatorLogService operatorLogService;
    @Resource
    private DatabaseService databaseService;
    @Resource
    private Site site;
    @Resource
    private UserService userService;

    // 引入数据库配置
    @Value("${spring.datasource.username}")
    private String dbusername;
    @Value("${spring.datasource.password}")
    private String dbpassword;
    @Value("${spring.datasource.url}")
    private String dburl;

    /**
     * 备份列表
     */
    @GetMapping("/dblist.do")
    public String backupDo(
            @RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
            Model model) {
        model.addAttribute("title", "数据库备份");

        if (ValidateMember.isEmpty(page) || page == 0) {
            page = 1;
        }

        int pagesize = Integer.parseInt(site.getPageSize());
        if (ValidateMember.isEmpty(pagesize)) {
            pagesize = Integer.MAX_VALUE;
        }
        // 定义 pageable
        Pageable pageable = PageRequest
                .of(page - 1, pagesize, Sort.by("createTime").descending().and(Sort.by("id").descending()));

        // 获取分页
        List<DatabasePO> allPage = databaseService.findAllPage(pageable);
        // 计算日志总条数
        Long logSize = databaseService.countAll();

        Long totalPage = logSize / pagesize;
        if (totalPage * pagesize < logSize) {
            totalPage++;
        }
        Integer currentPage = page;
        model.addAttribute("dblist", allPage);
        model.addAttribute("totalPage", totalPage);
        model.addAttribute("currentPage", currentPage);

        // 是否出现 前省略号
        Boolean befor_ellipsis = false;
        if (currentPage >= 4) {
            befor_ellipsis = true;
        }
        model.addAttribute("befor_ellipsis", befor_ellipsis);
        // 是否出现 前省略号
        Boolean after_ellipsis = false;
        if ((totalPage - currentPage) > 3) {
            after_ellipsis = true;
        }
        model.addAttribute("after_ellipsis", after_ellipsis);

        // b1 -- current -- a1
        // 分页b1 是否出现
        Boolean b1 = false;
        if (currentPage <= 2) {
            b1 = true;
        }
        model.addAttribute("b1", b1);
        // 分页a1 是否出现
        Boolean a1 = false;
        if ((totalPage - currentPage) <= 2) {
            a1 = true;
        }
        model.addAttribute("a1", a1);
        // 返回最后3页页码
        model.addAttribute("last00", totalPage - 1);
        model.addAttribute("last01", totalPage - 2);
        model.addAttribute("last02", totalPage - 3);
        // 中间页码
        model.addAttribute("mida", currentPage + 1);
        model.addAttribute("midb", totalPage - 1);

        // 中间分页
        Boolean mid = false;
        if (!b1 && !a1) {
            mid = true;
        }
        model.addAttribute("mid", mid);

        return "database/dblist";
    }

    /**
     * 数据库备份操作
     *
     * @return
     */
    @PostMapping(value = "/backup.ajax")
    @ResponseBody
    public AjaxResult backupAjax() throws IOException {
// 日志
        OperatorLogPO operatorLogPO = new OperatorLogPO();
        UserPO loninUser = SessionUtil.getLoninUser();
        if (ValidateMember.isEmpty(loninUser)) {
            return AjaxResult.fail(500, "系统卡顿,请重新登入");
        }

        UserPO userById = userService.findUserById(loninUser.getId());

        operatorLogPO.setUser(userById);
        operatorLogPO.setCreateTime(new Date());


        String dir = site.getBackupDirectory();
        File path = new File(dir);
        if (path.exists() && !path.isDirectory()) {
            operatorLogPO.setContent("备份数据库 目录存在,创建失败");
            operatorLogService.saveLog(operatorLogPO);
            return AjaxResult.fail(500, "目录存在,创建失败");
        }
        if (!path.exists()) {
            boolean mkdirs = path.mkdirs();
            if (!mkdirs) {
                operatorLogPO.setContent("备份数据库 目录不存在,创建失败");
                operatorLogService.saveLog(operatorLogPO);
                return AjaxResult.fail(500, "目录不存在,创建失败");
            }
        }

        String file = DateUtil.getBackupFileName();

        String allname = dir + file;

        // 测试文件是否存在
        File testFile = new File(allname);
        while (testFile.exists()) {
            file = DateUtil.getBackupFileName();
            allname = dir + file;
            testFile = new File(allname);
        }
        testFile = null;

        AjaxResult backup = databaseService.backup(dburl, dbusername, dbpassword, allname);
        if (backup.getCode() != 200) {
            operatorLogPO.setContent("备份数据库:" + backup.getMsg());
            operatorLogService.saveLog(operatorLogPO);
            return AjaxResult.success(500, "备份未能完成 " + backup.getMsg(), null);
        }

        operatorLogPO.setContent(backup.getMsg());
        operatorLogService.saveLog(operatorLogPO);

        return AjaxResult.success(200, "成功备份数据库", null);
    }

    /**
     * 删除备份 -- ajax
     */
    @PostMapping("/deletedb.ajax")
    @ResponseBody
    public AjaxResult deleteDbAjax(@RequestBody DatabasePO databasePO) {
        // 日志
        OperatorLogPO operatorLogPO = new OperatorLogPO();
        UserPO loninUser = SessionUtil.getLoninUser();
        if (ValidateMember.isEmpty(loninUser)) {
            return AjaxResult.fail(500, "系统卡顿,请重新登入");
        }

        UserPO userById = userService.findUserById(loninUser.getId());

        operatorLogPO.setUser(userById);
        operatorLogPO.setCreateTime(new Date());

        if (databasePO == null || ValidateMember.isEmpty(databasePO.getId())) {
            operatorLogPO.setContent("删除不合法");
            operatorLogService.saveLog(operatorLogPO);
            return AjaxResult.fail(500, "删除不合法");
        }
        DatabasePO byId = databaseService.findById(databasePO.getId());
        String filename = byId.getFilename();
        File test = new File(filename);
        if (!test.exists()) {
            operatorLogPO.setContent("备份文件不存在 删除失败");
            operatorLogService.saveLog(operatorLogPO);
            return AjaxResult.fail(500, "备份文件不存在:" + filename + " 删除失败");
        }

        AjaxResult result = databaseService.deleteById(byId.getId());

        if (result.getCode() != 200) {
            operatorLogPO.setContent(result.getMsg());
            operatorLogService.saveLog(operatorLogPO);
            return AjaxResult.fail(500, result.getMsg());
        }

        operatorLogPO.setContent("成功删除 数据库备份--" + filename);
        operatorLogService.saveLog(operatorLogPO);

        return AjaxResult.success(200, "成功删除 数据库备份", null);
    }

    /**
     * 编辑备份
     */
    @GetMapping("/editdb.do")
    public String editDbDo(@RequestParam(name = "id") Long id, Model model) {
        log.info("editdb.do id=" + id);
        model.addAttribute("title", "备份操作");
        DatabasePO byId = databaseService.findById(id);
        model.addAttribute("dbPO", byId);
        return "database/editdb";
    }

    /**
     * 修改备份
     */
    @PostMapping("/editdb.ajax")
    @ResponseBody
    public AjaxResult editDbAjax(@RequestBody DatabasePO databasePO) {
        if (ValidateMember.isEmpty(databasePO)) {
            return AjaxResult.fail(500, "数据有误");
        }
        DatabasePO byId = databaseService.findById(databasePO.getId());
        if (ValidateMember.isEmpty(byId)) {
            return AjaxResult.fail(500, "数据有误");
        }

        OperatorLogPO operatorLogPO = new OperatorLogPO();
        UserPO loninUser = SessionUtil.getLoninUser();
        UserPO userById = userService.findUserById(loninUser.getId());
        operatorLogPO.setUser(userById);
        operatorLogPO.setCreateTime(new Date());

        AjaxResult result = databaseService.saveComment(databasePO);
        if (result.getCode() != 200) {
            operatorLogPO.setContent(result.getMsg());
            operatorLogService.saveLog(operatorLogPO);
            return AjaxResult.fail(500, result.getMsg());
        } else {
            operatorLogPO.setContent(result.getMsg());
            operatorLogService.saveLog(operatorLogPO);
            return AjaxResult.success(200, result.getMsg(), null);
        }


    }

    /**
     * 恢复备份 restoredb.ajax
     */
    @PostMapping("/restoredb.ajax")
    @ResponseBody
    public AjaxResult restoreDbAjax(@RequestBody DatabasePO databasePO) throws IOException {

        if (ValidateMember.isEmpty(databasePO)) {
            return AjaxResult.fail(500, "数据有误");
        }
        DatabasePO byId = databaseService.findById(databasePO.getId());
        if (ValidateMember.isEmpty(byId)) {
            return AjaxResult.fail(500, "数据有误");
        }

        OperatorLogPO operatorLogPO = new OperatorLogPO();
        UserPO loninUser = SessionUtil.getLoninUser();
        UserPO userById = userService.findUserById(loninUser.getId());
        operatorLogPO.setUser(userById);
        operatorLogPO.setCreateTime(new Date());

        AjaxResult result = databaseService.restoreDb(databasePO, dburl, dbusername, dbpassword);

        if (result.getCode() != 200) {
            operatorLogPO.setContent(result.getMsg());
            operatorLogService.saveLog(operatorLogPO);

            return AjaxResult.fail(500, result.getMsg());
        } else {

            operatorLogPO.setContent(result.getMsg());
            operatorLogService.saveLog(operatorLogPO);

            return AjaxResult.success(200, result.getMsg(), null);

        }

    }

}
